#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#include "asm.h"


extern FILE * yyout;
extern treeTable *LinkTree;
//treeTable *global_statement = LinkTree;
VarList *variable_list;
Assembly gen;
extern char AutoRegSelect;
extern Num8 XmmSelect;
char *Tal="    ";
FuncParamsStack *FPS;
RunStatementInfo RSI;
Num4 stack_occupy=0;//最大4g栈空间

void INIT(){
    gen = *GetCodeGenerator();
    variable_list = GetVarListMemory();
    yyout = fopen("PLang.asm", "w+");
    
    fputs("section .data\n", yyout);
    fprintf(yyout, "%sversions db \"Lang: New-C Versions 0.0.1\",10\n", Tal);
    fprintf(yyout, "%sContributor db \"Contributor: Mr.Yuan\",10\n", Tal);
    fprintf(yyout, "%s_str db \"test a:%%n, b:%%n2, c:%%n4, d:%%n8 \",10\n", Tal);
    fputs("section .bss\n", yyout);
    fputs("section .rdata\n", yyout);
    fputs("section .text\n", yyout);
    fprintf(yyout, "%sglobal main\n", Tal); 
    fprintf(yyout, "%sextern out\n", Tal); 
    fputs("main:\n", yyout);
    
    ParserStatement(LinkTree, variable_list);
    
    
    fclose(yyout);
}
Num4 NoCount=0;
AsmFloatTAG *Asm_F_L , *lastAFL;
//设置浮点数
//TODO 整数的浮点数还不能识别
void InsAFL(variable *var, VarAttr va){
    if(var->type!=DATA_TYPE_F_NUMBER_4 && var->type!=DATA_TYPE_F_NUMBER_8 && var->type!=DATA_TYPE_STRING)return;
    if(va!=ATTR_CONSTANT)return;
    AsmFloatTAG *tmp = (AsmFloatTAG *)malloc(sizeof(AsmFloatTAG));
    tmp->No = NoCount++;
    tmp->type = var->type;
    tmp->f8   = var->value->f_number8;
    tmp->f4   = var->value->f_number4;
    tmp->string   = var->value->string;
    var->F_NO = tmp->No;
    if(!Asm_F_L){ // first
        Asm_F_L=tmp;
        lastAFL=tmp;
    }else{
        lastAFL->next = tmp;
        lastAFL = tmp;
    }
    
}

void WriteAFL(){
    for(AsmFloatTAG *p=Asm_F_L; p; p=p->next){
        if(p->type == DATA_TYPE_STRING){
            fprintf(yyout, "%sFLT%ld db \"%s\", 0\n",Tal,p->No, p->string);
            continue;
        }
        fprintf(yyout, "%sFLT%ld:\n",Tal,p->No);
        if(p->type == DATA_TYPE_F_NUMBER_4){
            fprintf(yyout, "%s%s%s%s%u\n",Tal,Tal, GetAsmSize(DATA_TYPE_F_NUMBER_4),Tal, p->f4->f2d);
        }else if(p->type == DATA_TYPE_F_NUMBER_8){
            fprintf(yyout, "%s%s%s%s%u\n",Tal,Tal, GetAsmSize(DATA_TYPE_F_NUMBER_8),Tal, p->f8->mem.l);
            fprintf(yyout, "%s%s%s%s%u\n",Tal,Tal, GetAsmSize(DATA_TYPE_F_NUMBER_8),Tal, p->f8->mem.h);
        }
        
    }
}

void PushFuncParamsContext(){
    FuncParamsStack *tmp = (FuncParamsStack *)malloc(sizeof(FuncParamsStack));
    tmp->is_func_params_parser=1;
    tmp->is_first=0;
    tmp->set_float_reg=0;
    tmp->set_no_float_reg=0;

    if(!FPS) tmp->next = FPS;
    FPS = tmp;
}
void PopFuncParamsContext(){
    FuncParamsStack *tmp = FPS;
    FPS = FPS->next;
    free(tmp);
}
float ToFloat(variable *t){
    if(t->type==DATA_TYPE_F_NUMBER_8) return (float) t->value->f_number8->f;
    return t->value->f_number4->f;
}
double ToDouble(variable *t){
    if(t->type==DATA_TYPE_F_NUMBER_4) return (double) t->value->f_number4->f;
    return t->value->f_number8->f;
}
void AsmMath(OperationType ot, _OBJ_ *target, _OBJ_ *source){
    switch(ot){
        case OP_ADD:
            gen.add(target, source);
            break;
        case OP_SUB:
            gen.sub(target, source);
            break;
        case OP_MUL:
            gen.imul(target, source);
            break;
        case OP_DIV:
            gen.idiv(target, source);
            break;
    }
}

variable *ParserStatement(treeTable *statement, VarList *var_list){
    /*
    为了调用gcc-x64函数, 必须按照它的方式设置栈和调用参数
    参数约定:
        非浮点数: rdi，rsi，rdx，rcx，r8，r9 6个参数以后依次入栈
        浮点数: xmm0~xmm7 8个参数后依次入栈
    */
    //进入程序
    fprintf(yyout, "%spush	rbp\n", Tal);   //保存栈
    fprintf(yyout, "%smov rbp, rsp\n", Tal);//设置栈

    // TODO优化: 当前程序块内没有调用其他函数, 可以不用减rsp
    if(stack_occupy != 0){
        //设置栈的长度 *16字节对齐, 
        //之所以选择16 (取余只能是2的次幂), 是因为可以按位与, 不用取余, 优化计算 (个人理解)
        char differ = stack_occupy&0x0f;
        Num inc=0;
        if(differ!=0) inc=16-differ;
        fprintf(yyout, "%ssub rsp, %ld\n", Tal, stack_occupy+inc );
    }
    fprintf(yyout, "\n"); 
    
    // printf("ParserStatement start\n");
    RunStatement(statement, var_list);
    // printf("ParserStatement end\n");

    //退出程序
    fprintf(yyout, "\n"); 
    fprintf(yyout, "%sleave\n", Tal); //恢复栈
    fprintf(yyout, "%sret\n", Tal); //退出

    fprintf(yyout, "section .data\n");
    //写入所有标号
    WriteAFL();
}

void TmpPrinf(DataType t){
    switch (t)
    {
        case DATA_TYPE_NUMBER_1: printf("DATA_TYPE_NUMBER_1\n"); break;
        case DATA_TYPE_NUMBER_2: printf("DATA_TYPE_NUMBER_2\n"); break;
        case DATA_TYPE_NUMBER_4: printf("DATA_TYPE_NUMBER_4\n"); break;
        case DATA_TYPE_NUMBER_8: printf("DATA_TYPE_NUMBER_8\n"); break;
        case DATA_TYPE_F_NUMBER_4: printf("DATA_TYPE_F_NUMBER_4\n"); break;
        case DATA_TYPE_F_NUMBER_8: printf("DATA_TYPE_F_NUMBER_8\n"); break;
        case DATA_TYPE_STRING: printf("DATA_TYPE_STRING\n"); break;
    }
}
void TmpPrinf2(VarAttr t){
    switch (t)
    {
        case ATTR_CONSTANT: printf("ATTR_CONSTANT\n"); break;
        case ATTR_VAR: printf("ATTR_VAR\n"); break;
        case ATTR_RETURN: printf("ATTR_RETURN\n"); break;
    }
}

variable *RunStatement(treeTable *statement, VarList *var_list){
    static int layer;
    layer++;
    // printf("`RunStatement` layer:%d\n" , layer);
    
    /*
        TODO 调用层级需要限制
        逻辑上, 保存当前寄存器数据的空间有限
        业务上, 调用嵌套太深增加CPU耗时严重
    */
    treeTable *p;
    //TODO 保存寄存器数据
    
    for(p=statement; p&&p->node; p=p->next){

        // if(FPS && FPS->is_func_params_parser==1 && FPS->set_float_reg<=8){
        //     XmmSelect=FPS->set_float_reg;
        // }

        variable *val = RunTree(p->node, var_list);
        //重置寄存器数据
        AutoRegSelect=0;
        XmmSelect=0;
        /*
        RSI.is_first=0;
        if(FPS && FPS->is_func_params_parser==1){
            if(FPS->is_first==0 && FPS->set_stack_mem>0) {
                FPS->is_first=1;
                fprintf(yyout, "%ssub rsp, %ld\n", Tal, FPS->set_stack_mem );
            }
            if(val->attr == ATTR_CONSTANT && is_no_float(val->type)){
                if(val->type == DATA_TYPE_STRING){
                    InsAFL(val, ATTR_CONSTANT);
                    gen.lea(ax(DATA_TYPE_STRING), memrel(val->F_NO) );
                }else{
                    gen.mov(ax(val->type), imm(GetNumber(val)) );
                }
            }else if(val->attr == ATTR_CONSTANT && is_float(val->type)){
                //if(FPS->set_float_reg<=8) XmmSelect=FPS->set_float_reg;
                // push xmm0
                InsAFL(val, ATTR_CONSTANT);
                gen.fmov(val->type, xmm(), memrel(val->F_NO) );
            }
            
            if(is_no_float(val->type)){
                //ax
                StackReg(FPS->set_no_float_reg, val->type);
                FPS->set_no_float_reg--;
            }else{
                //xmm0
                StackXmm(FPS->set_float_reg-1, val->type);
                FPS->set_float_reg--;
            }
        }
        */
    }

    layer--;
}
variable *RunTree(tree *expr, VarList *var_list){
    static int count;
    // printf("CallFunc `RunTree` count:%d\n" , ++count);
    variable *ret_val;
    switch (expr->type)
    {
        case EXPR_BINARY:{
            if(dis_expr_code) printf("EXPR_BINARY\n");
            variable *left = RunTree(expr->entity.operation_v->left, var_list);
            //TODO 检测right如果是优先运算 left->attr==ATTR_RETURN
            //需要把 ax的值pop到栈内
            char prec=expr->entity.operation_v->right->entity.operation_v->prec;
            if(prec==1 && left->attr==ATTR_RETURN){
                gen.push(ax(DATA_TYPE_NUMBER_8));
                prec=1;
            }
            variable *right = RunTree(expr->entity.operation_v->right, var_list);
            if(prec==1 && left->attr==ATTR_RETURN){
                gen.push(ax(DATA_TYPE_NUMBER_8));
                gen.pop(dx(DATA_TYPE_NUMBER_8));
                gen.pop(ax(DATA_TYPE_NUMBER_8));
            }
            ret_val = mallocVariable();
            ret_val->value->f_number8 = (F64 *)malloc(sizeof(F64));
            //if(check_number(left->type)){ }
            /*
            if(left->attr !=ATTR_CONSTANT && right->attr != ATTR_CONSTANT && left->type != right->type)
            {
                // TODO 类型错误 不能进行二目运算
                printf("number type error \n");
                exit(0);
            }*/
            
            ret_val->type=DATA_TYPE_F_NUMBER_8;
            ret_val->attr=ATTR_RETURN;
            char is_f = 0; //是否浮点数
            if(left->is_float|| right->is_float ) is_f=1;
            ret_val->is_float=is_f;
            
            switch(expr->entity.operation_v->type){
                case OP_ADD:
                    ret_val->value->f_number8->f = Var2Double(left) + Var2Double(right);
                    break;
                case OP_SUB:
                    ret_val->value->f_number8->f = Var2Double(left) - Var2Double(right);
                    break;
                case OP_MUL:
                    ret_val->value->f_number8->f = Var2Double(left) * Var2Double(right);
                    break;
                case OP_DIV:
                    ret_val->value->f_number8->f = Var2Double(left) / Var2Double(right);
                    break;
            }
            if(left->attr == ATTR_CONSTANT && right->attr == ATTR_CONSTANT){
                ret_val->attr=ATTR_CONSTANT;
                break;
            }
            // left类型 : ret var const
            // right类型: const var  ret
            // 编码设计原理, 有符号正负整数可以直接加减
            // 乘除 必须使用有符号指令
            if(left->attr == ATTR_CONSTANT){

                if(right->attr==ATTR_VAR){
                    gen.mov(dx(right->type), mem(right->position_stack, bp(right->type)));
                    DataType t=gen.movsx(dx(right->type), dx(right->type));

                    // TODO 数字类型被处理成 双字节整数, 并不知道具体的类型
                    // 目前取另一个运算类型,为数字类型
                    gen.mov(ax(t), imm(GetNumber(left)));
                    AsmMath(expr->entity.operation_v->type, ax(t), dx(t));
                    ret_val->type = t;
                }else if(right->attr==ATTR_RETURN){
                    DataType t=right->type;
                    //把right的值转到bx
                    gen.mov(dx(DATA_TYPE_NUMBER_8), ax(DATA_TYPE_NUMBER_8));
                    gen.mov(ax(t), imm(GetNumber(left)));
                    AsmMath(expr->entity.operation_v->type, ax(t), dx(t));
                    ret_val->type = t;
                }
               
            }else if(left->attr == ATTR_RETURN){
                //ax被占用
                if(right->attr == ATTR_CONSTANT){
                    AsmMath(expr->entity.operation_v->type,ax(left->type), imm(GetNumber(right)));
                    ret_val->type = left->type;
                }else if(right->attr == ATTR_VAR){ 
                    gen.mov(dx(right->type), mem(right->position_stack, bp(right->type)));
                    DataType t=gen.movsx(dx(left->type), dx(right->type));
                    AsmMath(expr->entity.operation_v->type,ax(t), dx(t));
                    ret_val->type = t;
                }else if(right->attr==ATTR_RETURN){
                    DataType t=right->type;
                    AsmMath(expr->entity.operation_v->type, ax(t), dx(t));
                    ret_val->type = t;
                }

            }else if(left->attr == ATTR_VAR){
                if(right->attr == ATTR_CONSTANT){
                    gen.mov(ax(left->type), mem(left->position_stack, bp(left->type)));
                    DataType t=gen.movsx(ax(left->type), ax(left->type));
                    AsmMath(expr->entity.operation_v->type,ax(t), imm(GetNumber(right)));
                    ret_val->type = t;
                }else if(right->attr == ATTR_VAR){ 
                    gen.mov(ax(left->type), mem(left->position_stack, bp(left->type)));
                    gen.movsx(ax(right->type), ax(left->type));
                    gen.mov(dx(right->type), mem(right->position_stack, bp(right->type)));
                    DataType t=gen.movsx(dx(left->type), dx(right->type));
                    AsmMath(expr->entity.operation_v->type,ax(t), dx(t));
                    ret_val->type = t;
                }else if(right->attr==ATTR_RETURN){
                    //把right的值放到bx
                    gen.mov(dx(DATA_TYPE_NUMBER_8), ax(DATA_TYPE_NUMBER_8));
                    gen.mov(ax(left->type), mem(left->position_stack, bp(left->type)));
                    DataType t=gen.movsx(ax(right->type), ax(left->type));
                    AsmMath(expr->entity.operation_v->type,ax(t), dx(t));
                    ret_val->type = t;
                }
            }
            break;
        }
        case EXPR_DEF_VAR:{
            if(dis_expr_code) printf("EXPR_DEF_VAR\n");
            variable *var = expr->entity.var_v;
            variable *tmp_var = GetMapValue(var_list, var->name, 0);
            if(tmp_var) {
                // 重复申请
                printf("repeat create variable: %s\n", var->name);
                exit(0);
            }
            variable *new_var = CopyVariable(var);
            new_var->position_stack = stack_occupy;
            sub_stack(stack_occupy, var->type);
            //设置变量
            SetValue(var_list->var, new_var, new_var->name);
            if(RSI.is_first==0) RSI.result_type = var->type;
            break;
        }
        case EXPR_VAR_CONSTANT:{
            if(dis_expr_code) printf("EXPR_VAR_CONSTANT\n");
            if(expr->entity.var_v->attr == ATTR_VAR)
            {
                ret_val= GetMapValue(var_list, expr->entity.var_v->name, 0);
                if(!ret_val) {
                    // 没有找到变量
                    printf("not find variable: %s\n", expr->entity.var_v->name);
                    exit(0);
                }
                /*
                if(is_float(ret_val->type)){
                    if(is_float(RSI.result_type) && ret_val->type!=RSI.result_type && RSI.result_type==DATA_TYPE_F_NUMBER_4){
                        //双精度缩减单精度 cvtsd2ss
                        gen.cvtsd2(1, xmm(), mem(ret_val->position_stack, bp(ret_val->type)) );
                    }else if(is_float(RSI.result_type) && ret_val->type!=RSI.result_type && RSI.result_type==DATA_TYPE_F_NUMBER_8){
                        //单精度扩展双精度 cvtss2sd
                        gen.cvtsd2(2, xmm(), mem(ret_val->position_stack, bp(ret_val->type)) );
                    }else{
                        gen.fmov(ret_val->type, xmm(), mem(ret_val->position_stack, bp(ret_val->type)) );
                    }
                    
                }else{
                    gen.mov(AutoReg(ret_val->type), mem(ret_val->position_stack, bp(ret_val->type)) );
                }
                */
            }else{
                ret_val = expr->entity.var_v;
                // 无法知道接下来是2个纯数字相加, 所以不能记录浮点数
            }
            break;
        }
        case EXPR_ASSIGN:{
                if(dis_expr_code) printf("EXPR_ASSIGN\n");
                //左边一定是变量直接取
                variable *key = expr->entity.assign_v->left->entity.var_v;
                variable *entity_key = GetMapValue(var_list, key->name, 0);
                if(RSI.is_first==0) RSI.result_type = entity_key->type;

                //右边需要解析树
                variable *val = RunTree(expr->entity.assign_v->right, var_list);

                //赋值
                evaluation(val, entity_key);
                //设置浮点列表
                InsAFL(entity_key, val->attr);
                //记录浮点 no.?
                //VarPutFNo(entity_key, val->F_NO);
                if(val->attr==ATTR_CONSTANT){
                    if(entity_key->type==DATA_TYPE_F_NUMBER_4 || entity_key->type==DATA_TYPE_F_NUMBER_8){
                        gen.fmov(entity_key->type, xmm(), memrel(entity_key->F_NO));
                        gen.fmov(entity_key->type, mem(entity_key->position_stack, bp(entity_key->type)), xmm());
                    }else{
                        gen.mov(mem(entity_key->position_stack, bp(entity_key->type)), imm(GetNumber(val)) );
                    }
                }else{
                    if(entity_key->type==DATA_TYPE_F_NUMBER_4 || entity_key->type==DATA_TYPE_F_NUMBER_8){
                        // Debug
                        //例如2个 double相加, 值在xmm->64位里面
                        //但是entity_key->type==DATA_TYPE_F_NUMBER_4 就会操作xmm->32位
                        gen.fmov(entity_key->type, mem(entity_key->position_stack, bp(entity_key->type)), xmm());
                    }else
                        gen.mov(mem(entity_key->position_stack, bp(entity_key->type)), ax(entity_key->type) );
                }
                break;
            }
        case EXPR_CALL_FUNC:{
            if(dis_expr_code) printf("EXPR_CALL_FUNC\n");
            char *func_name = expr->entity.func_call_v->name;
            //如果是out函数需要从第一个字符串参数
            //解析出可变参数的个数(浮点数和非浮点数分别多少个)
            PushFuncParamsContext();
            if(strcmp(func_name, "out") == 0){
                RSI.result_type = DATA_TYPE_F_NUMBER_8;
                // TODO 字符串还没写规则
                treeTable *lsat=GetLsatTree(expr->entity.func_call_v->params);
                variable *val =RunTree(lsat->node, var_list);
                if(val->type != DATA_TYPE_STRING); //TODO 第一个参数必须是字符串
                Num4 i=0;
                while (val->value->string[i] != '\0'){
                    if(val->value->string[i] != '%'){
                        i++;
                        continue;
                    } 
                    switch (val->value->string[++i])
                    {
                        case 's': FPS->set_no_float_reg++; break;  
                        case 'd': FPS->set_float_reg++; break;
                        case 'f': FPS->set_float_reg++; break;
                        case 'n': FPS->set_no_float_reg++; break;
                        default : break;
                    }
                    i++;
                }

                FPS->set_no_float_reg++;//out第一个参数
                
            }else{

            }

            //计算栈空间
            Num4 stack_mem =(FPS->set_no_float_reg-6)<1?0:(FPS->set_no_float_reg-6)*8;
            stack_mem +=(FPS->set_float_reg-8)<1?0:(FPS->set_no_float_reg-8)*8;
            Num differ = stack_mem&0x0f;
            Num inc=0;
            if(differ!=0) inc=16-differ; //inc 下1个16的倍数相差
            FPS->set_stack_mem = (stack_mem+inc)-stack_mem;
            // printf("stack_mem: %ld \n", FPS->set_stack_mem);
            // if(FPS->set_stack_mem>0) {
            //     fprintf(yyout, "%ssub rsp, %ld\n", Tal, FPS->set_stack_mem );
            // }
            RunStatement(expr->entity.func_call_v->params, var_list);
            // recursive_reverse(expr->entity.func_call_v->params)
            PopFuncParamsContext();


            //gcc-64 外平栈
            if( (stack_mem+inc)>0) fprintf(yyout, "%sadd  rsp, %ld\n", Tal, stack_mem+inc);
            
            break;
        }
        default:
            printf("expr voer\n");
            exit(0);
            break;
    }
    RSI.is_first=1;
    return ret_val;   
}
treeTable * GetLsatTree(treeTable * head){
    if (head == NULL || head->next == NULL) return head;
    
    treeTable *lsat;
    for(lsat=head;lsat->next;lsat=lsat->next);
    return lsat;
}

/*
    链表递归反转
treeTable * recursive_reverse(treeTable * head) {
    if (head == NULL || head->next == NULL)
        return head; 
    else { 
        treeTable *new_head = recursive_reverse(head->next);  
        head->next->next = head; 
        head->next = NULL; 
        return new_head; 
    }
}
*/
char * GetAsmSize(DataType type){
    if(type==DATA_TYPE_NUMBER_1){
        return ASM_SIZE_DB;
    }else if(type==DATA_TYPE_NUMBER_2){
        return ASM_SIZE_DW;
    }else if(type==DATA_TYPE_NUMBER_4){
        return ASM_SIZE_DD;
    }else if(type==DATA_TYPE_NUMBER_8){
        return ASM_SIZE_DQ;
    }else if(type==DATA_TYPE_F_NUMBER_4||type==DATA_TYPE_F_NUMBER_8){
        return ASM_SIZE_DD;
    }
}


variable *CopyVariable(variable *source){
    variable * ret = (variable *)malloc(sizeof(variable));
    ret->type = source->type;
    //ret->is_float = source->is_float;
    ret->attr = source->attr;
    ret->position_stack = source->position_stack;
    ret->F_NO = source->F_NO;
    ret->is_float = source->is_float;
    if(source->name) ret->name = strdup(source->name);
    ret->value = (values *)malloc(sizeof(values));
    
    if(source->arr){
        ret->arr = (array *)malloc(sizeof(array));
        ret->arr->layers = source->arr->layers;
        ret->arr->count = source->arr->count;
        ret->arr->base = (Num2 *)calloc(source->arr->layers, sizeof(Num2));
        ret->arr->map = (Num2 *)calloc(source->arr->layers, sizeof(Num2));
        memcpy(ret->arr->base, source->arr->base, source->arr->layers);
        memcpy(ret->arr->map, source->arr->map, source->arr->layers);
    }
    
   return ret;
}
void evaluation(variable *source, variable *target){
    if(target->type==DATA_TYPE_NUMBER_1){
        if(!target->value->number) target->value->number = (Num*)malloc(sizeof(Num));
        *target->value->number= (Num)GetNumber(source);
    }else if(target->type==DATA_TYPE_NUMBER_2){
        if(!target->value->number2) target->value->number2 = (Num2*)malloc(sizeof(Num2));
        *target->value->number2= (Num2)GetNumber(source);
    }else if(target->type==DATA_TYPE_NUMBER_4){
        if(!target->value->number4) target->value->number4 = (Num4*)malloc(sizeof(Num4));
        *target->value->number4= (Num4)GetNumber(source);
    }else if(target->type==DATA_TYPE_NUMBER_8){
        if(!target->value->number8) target->value->number8 = (Num8*)malloc(sizeof(Num8));
        *target->value->number8= GetNumber(source);
    }else if(target->type==DATA_TYPE_F_NUMBER_4){
        if(!target->value->f_number4) target->value->f_number4 = (F32*)malloc(sizeof(F32));
        target->value->f_number4->f = (float)source->value->f_number8->f;
        
        if( source->type==DATA_TYPE_F_NUMBER_8){
            target->value->f_number4->f = (float)source->value->f_number8->f;
        }else{
            target->value->f_number4->f = source->value->f_number4->f;
        }
        
       
        
    }else if(target->type==DATA_TYPE_F_NUMBER_8){
        if(!target->value->f_number8) target->value->f_number8 = (F64*)malloc(sizeof(F64));
        target->value->f_number8->f = source->value->f_number8->f;
    }
        
    
}
Num8 GetNumber(variable *source){
    if(source->type==DATA_TYPE_NUMBER_1){
        return (Num8)*source->value->number;
    }else if(source->type==DATA_TYPE_NUMBER_2){
        return (Num8)*source->value->number2;
    }else if(source->type==DATA_TYPE_NUMBER_4){
        return (Num8)*source->value->number4;
    }else if(source->type==DATA_TYPE_NUMBER_8){
        return *source->value->number8;
    }else if(source->type==DATA_TYPE_F_NUMBER_4){
        return (Num8)source->value->f_number4->f;
    }else if(source->type==DATA_TYPE_F_NUMBER_8){
        return (Num8)source->value->f_number8->f;
    }
}

